using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace Core.Mapping
{
    public enum TerrainTypes
    {
        WaterShallow = 0,
        WaterMedium = 1,
        WaterDeep = 2,
        RiverSlow = 3,
        RiverMedium = 4,
        RiverFast = 5,
        Lake = 10,
        Ocean = 11,
        PlainsShortGrass = 12,
        PlainsMediumGrass = 13,
        PlainsTallGrass = 14,
        DesertSandy = 20,
        DesertSandyRock = 21,
        DesertBarrenRock = 22,
        RockySmallBoulders = 23,
        RockyMediumBoulders = 24,
        RockyLargeBoulders = 25,
        IceSpotty = 30,
        IceThin = 31,
        IceMedium = 32,
        IceThick = 33,
        BogShallow = 40,
        BogMedium = 41,
        BogDeep = 42,
        JungleSparse = 45,
        JungleMedium = 46,
        JungleImpassable = 47,
        ForestSparse = 50,
        ForestMedium = 51,
        ForestImpassable = 52,
        TrailUnmaintened = 53,
        TrailMaintened = 54,
        RoadDirt = 60,
        RoadPaved = 61,
        City = 62
    }

    public enum HillinessTypes
    {
        Flat = 0,
        HillsSmall = 5,
        HillsMedium = 6,
        HillsLarge = 7,
        MountainSmall = 10,
        MountainMedium = 11,
        MountainLarge = 12
    }

    public enum SoilTypes
    {
        Mix = 0,
        Clay = 5,
        Silt =  10,
        Sandy = 15
    }

    [Serializable()]
    public class LandTile
    {
        /// <summary>Type of Terrain for this Land</summary>
        public TerrainTypes Terrain { get { return _Terrain; } set { _Terrain = value; } }
        /// <summary>Hilliness of Terrain for this Land</summary>
        public HillinessTypes Hilliness { get { return _Hilliness; } set { _Hilliness = value; } }
        /// <summary>Type of Soil this Land has</summary>
        public SoilTypes Soil { get { return _Soil; } set { _Soil = value; } }

        protected TerrainTypes _Terrain = TerrainTypes.PlainsShortGrass;
        protected HillinessTypes _Hilliness = HillinessTypes.Flat;
        protected SoilTypes _Soil = SoilTypes.Mix;

        public static LandTile DefaultLandTile
        {
            get { if (_DefaultLandTile == null) { _DefaultLandTile = new LandTile(); } return _DefaultLandTile; }
        }
            
        protected static LandTile _DefaultLandTile;

        public LandTile()
        {
            //For default values or XML Serialization
        }

        public LandTile(TerrainTypes Terrain, HillinessTypes Hilliness, SoilTypes Soil)
        {
            _Terrain = Terrain;
            _Hilliness = Hilliness;
            _Soil = Soil;
        }

        protected static BitVector32.Section bvsTerrainType = BitVector32.CreateSection(100);
        protected static BitVector32.Section bvsHilliness = BitVector32.CreateSection(20, bvsTerrainType);
        protected static BitVector32.Section bvsSoilType = BitVector32.CreateSection(30, bvsHilliness);

        public static int GetLandTileAsBitVector(LandTile Tile)
        {
            BitVector32 bvTile = new BitVector32(0);

            bvTile[bvsTerrainType] = (int)Tile.Terrain;
            bvTile[bvsHilliness] = (int)Tile.Hilliness;
            bvTile[bvsSoilType] = (int)Tile.Soil;

            return bvTile.Data;
        }

        public static LandTile GetLandTileFromBitVector(int Data)
        {
            BitVector32 bvTile = new BitVector32(Data);

            return new LandTile(
                (TerrainTypes)bvTile[bvsTerrainType], 
                (HillinessTypes)bvTile[bvsHilliness], 
                (SoilTypes)bvTile[bvsSoilType]);
        }
    }
}
